from Common.EventHandle import EventHandle
from Calendar.Calendar import *

from FinancialAsset.AssetFactory import *
from DataFeeder.QueryQuote import *
from Misc.QuoteType import *

from Config.TradeCost import *	
		
class TargetWeight(EventHandle):

	def __init__(self, start_date, end_date):
	
		trd_dates = TradingCalendar(['CNSESH']).date_series(start_date, end_date, Frequency.Daily)

		EventHandle.__init__(self, trd_dates)

	def create_activities(self, ref_date, portf = None):
	
		print 'running info...', ref_date.isoformat()

		holding = portf.holding(ref_date)
		print '   step 1, acquring holding completed.'
		
		nav = portf.nav(ref_date)
		print '   step 2, acquring nav completed.', nav
		
		target_wgt = self.create_target_wgt(ref_date)
		target_position = {}
		for elem in target_wgt:
			stock = AssetFactory().acquire_asset('STOCK', elem[0])
			close = QuoteRegister().get_stock_quote(ref_date, elem[0], QuoteType.CLOSE)
			target_position[stock] = round(nav * elem[1] / close)
		
		#generate target trades
		trd_list = []
		
		for elem in set(holding.keys())|set(target_position.keys()):
		
			if elem.type_name() == 'CASH':
				continue
			
			holding_quantity = holding[elem] if holding.has_key(elem) else 0
			target_quantity = target_position[elem] if target_position.has_key(elem) else 0
			
			cash = AssetFactory().acquire_asset('CASH', elem.currency())
			cost_price = QuoteRegister().get_stock_quote(ref_date, elem.ticker(), QuoteType.CLOSE)
			
			trd_amount = target_quantity - holding_quantity
			if trd_amount > 0: #BUY
				cost = -trd_amount*cost_price*(1 + STOCK_BUY_COST)
			else: #SELL
				cost = -trd_amount*cost_price*(1 - STOCK_SELL_COST)
			
			trd_list.append((ref_date, elem, trd_amount))
			trd_list.append((ref_date, cash, cost))
			
		print '   step 3, creating trades completed.'
			
		return trd_list
		
	def create_target_wgt(self, ref_date):
		#return [(tick,wgt)]
		return [('600143', 0.5)]
		
	@staticmethod	
	def event_name():
		return 'Target Weight'